#!/usr/bin/env python

import sys
import os
import time
import re
import tarfile
import subprocess
from optparse import OptionParser

#init
fulldump_dir = "./backup/fulldump/"
binlog_dir = "./backup/"
binlog_files = []
mysqlbin_dir = "/usr/local/mysql/bin/"

usage = "usage: %prog -t 'YYYY-MM-DD HH:MM:SS'"
parser = OptionParser(usage)
parser.add_option("-t", "--time", dest = "time", help = "input time: 'YYYY-MM-DD HH:MM:SS'")
(option, args) = parser.parse_args()
if option.time == None:
    parser.error("-t input time: 'YYYY-MM-DD HH:MM:SS'")

try:
    tArray = time.strptime(option.time, '%Y-%m-%d %H:%M:%S')
except ValueError as e:
    print "Error: %s " % e
    sys.exit(1)
t = time.mktime(tArray)


def Get_fulldump_file():
    try:
        fulldump_files_all = os.listdir(fulldump_dir)
    except OSError:
        print "Error: not in correct directory!"
        sys.exit(1)
    fulldump_file = {}
    
    for file in fulldump_files_all:
        matchFile = re.match(r'mysql_backup.*[.]sql[.]gz', file)
        if matchFile:
            file = fulldump_dir + file
            time_file = os.path.getctime(file) 
            if t >= time_file:
                fulldump_file[file] = time_file
    
    if fulldump_file == {}:
        print "could not find fulldump files"
        sys.exit(1)

    fulldump_file = sorted(fulldump_file.items(), key = lambda fulldump_file:fulldump_file[1])
    fulldump_file = fulldump_file[-1][0]
    time_end = os.path.getctime(fulldump_file)
    if t >= time_end + 86400:
        print "could not find fulldump files"
        sys.exit(1) 

    return fulldump_file


def Get_binlog_files(log_file):
    try:
        binlog_files_all = os.listdir(binlog_dir)
    except OSError:
        print "Error: not in correct directory!"
        sys.exit(1)
    
    try:
        f = open(log_file)
        binlog_start = binlog_dir + f.readlines()[1].strip().split('\t')[0]
        f.close
    except IOError:
        print "Error: could not find log file"
        sys.exit(1)

    time_start = os.path.getctime(binlog_start)
    binlog_files = {}
    binlog_files[binlog_start] = time_start
    
    for file in binlog_files_all:
        matchFile = re.match(r'mysql-bin.\d{6}$', file)
        if matchFile:
            file = binlog_dir + file
            time_file = os.path.getctime(file)
            if time_start < time_file <= t:
                binlog_files[file] = time_file
    
    if binlog_files == {}:
        print "could not find binlog files"
        sys.exit(1)

    binlog_files = sorted(binlog_files.items(), key = lambda binlog_files:binlog_files[1])
    binlog_files = [file for file, time in binlog_files]
    binlog_files = ' '.join(binlog_files)
    return binlog_files    
       

def Binlog_to_sql(binlog_files):
    cmd = mysqlbin_dir + 'mysqlbinlog ' + binlog_files + ' --stop-datetime="' + option.time + '" -d database -r ' + '/tmp/time.sql'
    print 'binlog to sql ...'
    subprocess.check_call(cmd, shell=True)
    sqlfile = "/tmp/time.sql"
    return sqlfile

def package(fulldump_file, sqlfile):
    t = time.strftime('%Y-%m-%d-%H-%M-%S', tArray)
    f = './download/mysqlbackup-' + t + '.tar.gz'
    tar = tarfile.open(f, "w:gz")
    tar.add(fulldump_file)
    tar.add(sqlfile)
    tar.close()
    print "%s is ready." % (f)
    

if __name__ == "__main__":
    fulldump_file = Get_fulldump_file()
    log_file = fulldump_dir + os.path.basename(fulldump_file).split('.')[0] + '.log'
    binlog_files = Get_binlog_files(log_file)
    sqlfile = Binlog_to_sql(binlog_files)
    package(fulldump_file, sqlfile)
